/*
Project : Programmable Feedback Control of Airflow System for Pre-term infant oxygen saturation
Microcontroller : STM32F4 Discovery (STM32F407VG)
File : main.c
*/

#include "stm32f4xx.h"
#include <stdio.h>
#include "main.h"
#include "stm32f4xx_conf.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_usart.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_adc.h"
#include "stm32f4xx_spi.h"
#include "stm32f4xx_tim.h"

//******************************************************************************
void usart_setup(void);
void adc_setup(void);
void spi_setup(void);
int fputc(int ch, FILE *f);
void delay(void);
void scanf1(void);
void adc_printf(void);
//******************************* Variable **************************************
unsigned char msg ;
uint16_t adc_value, DAC_data, DAC_real;
//******************************* Main Function ********************************
int main()
{	
	/* Set Up config System*/
	usart_setup();
	adc_setup();
	spi_setup();
	STM_EVAL_LEDInit(LED3);
	STM_EVAL_LEDInit(LED4);
	STM_EVAL_LEDOn(LED3);
	STM_EVAL_LEDOn(LED4);
	
	/*
	while(1)
	{
		//Start ADC Convertor
		ADC_SoftwareStartConv(ADC1);
		while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
		adc_value = ADC_GetConversionValue(ADC1);
		printf("The Value from ADC = %d \n",&adc_value);
		delay();
		STM_EVAL_LEDOff(LED3);
		delay();
	}
	*/
	
	//SPI transfer data to DAC IC (LTC 1661,10 bits)
	/*
		Header code for transfer SPI to LTC 1661 (DAC 10 bits)
		Control Code (A3 A2 A1 A0)
		1 0 0 1 	- 	Load Input Reg A (Load DAC A), Output Update, HEX : 9FFF
		1 0 1 0 	-		Load Input Reg B (Load DAC B), Output Update, HEX : AFFF
		
		Data DAC Reg is 10 bits (D9 - D0)
		
		Don't care 2 bits (X1,X0)
	*/
	
	while(1)
	{
		DAC_data = 0x299;
		DAC_data =(DAC_data<<2) && 0x9FFF;
		//function for transfer data to DAC IC
		SPI_I2S_SendData(SPI2,DAC_data);
		delay();
		/*if(DAC_real == 0x3FF)
		{
			DAC_real = 0x000;
		}else
		{
			DAC_real++;
		}*/
	}
}
//******************************************************************************
void usart_setup(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	USART_InitTypeDef USART_InitStruct;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	/* Connect PXx to USARTx_Tx*/
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
  /* Connect PXx to USARTx_Rx*/
  GPIO_PinAFConfig( GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
	
	/*
		Use Port A Pin PA2 to Tx
		Use Port A Pin PA3 to Rx
	*/
	
	/* set GPIO init structure parameters values */
  GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_2 | GPIO_Pin_3;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	
	/* USART_InitStruct members default value */
  USART_InitStruct.USART_BaudRate = 9600;
  USART_InitStruct.USART_WordLength = USART_WordLength_8b;
  USART_InitStruct.USART_StopBits = USART_StopBits_1;
  USART_InitStruct.USART_Parity = USART_Parity_No ;
  USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
	USART_Init(USART2, &USART_InitStruct);

	//Enable USART1
	USART_Cmd(USART2, ENABLE);
}

void scanf1(void)
{
		while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET);
		msg = USART_ReceiveData(USART2);
}
int fputc(int ch, FILE *f)
{
	/* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(USART2, (uint8_t) ch);
  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
  {}
	return ch;
}
//*********************** ADC SETUP ************************************
void adc_setup(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	ADC_InitTypeDef ADC_InitStruct;
	/*
		use ADC1_IN6  Port A pin PA6
	*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); 
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 
	
	/* set GPIO init structure parameters values */
  GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_6;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	
  /* Initialize the ADC_Mode member */
  ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
  /* initialize the ADC_ScanConvMode member */
  ADC_InitStruct.ADC_ScanConvMode = DISABLE;
  /* Initialize the ADC_ContinuousConvMode member */
  ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;
  /* Initialize the ADC_ExternalTrigConvEdge member */
  ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  /* Initialize the ADC_ExternalTrigConv member */
  ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
  /* Initialize the ADC_DataAlign member */
  ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
  /* Initialize the ADC_NbrOfConversion member */
  ADC_InitStruct.ADC_NbrOfConversion = 1;
	ADC_Init(ADC1,&ADC_InitStruct);
	
	//Enable ADC1
	ADC_Cmd(ADC1, ENABLE);
	
	ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1,ADC_SampleTime_28Cycles);
}

//*********************** SPI setup ************************************
void spi_setup(void)
{
	/*
			use SPI2 for Transfer data to DAC IC
	*/
	GPIO_InitTypeDef GPIO_InitStruct;
	SPI_InitTypeDef SPI_InitStruct;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
	/*
			PB12 = SPI2_NSS
			PB13 = SPI2_CLK
			PB14 = SPI2_MISO (Master in Slave out)
			PB15 = SPI2_MOIS (Master out Slave in)
	*/
	
	/* set GPIO init structure parameters values */
  GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	
	//Config SPI
  SPI_InitStruct.SPI_Direction = SPI_Direction_1Line_Tx;						// Tx Only
  SPI_InitStruct.SPI_Mode = SPI_Mode_Slave;
  SPI_InitStruct.SPI_DataSize = SPI_DataSize_16b;										//Data size is 16 bits for transfer data 10 bits to DAC IC
  SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
  SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
  SPI_InitStruct.SPI_NSS = SPI_NSS_Hard;
  SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
  SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStruct.SPI_CRCPolynomial = 7;
	SPI_Init(SPI2, &SPI_InitStruct);
	
	//Enable SPI2
	SPI_Cmd(SPI2,ENABLE);
}
//*********************** delay function *******************************
void delay(void)
{
	unsigned int i,j;
	for(i=0;i<5000;i++)
	{
		for(j=0;j<300;j++);
	}
}

/*This Function is Analog to Digital Converter and Sent data via RS-232 (USART)(Printf) */
void adc_printf(void)
{
	adc_value = 0;
	//Start ADC Convertor
	ADC_SoftwareStartConv(ADC1);
	while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
	adc_value = ADC_GetConversionValue(ADC1);
	printf("The Value from ADC = %d \n",&adc_value);
}
